package edu.uwm.cs552.util;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import javax.swing.AbstractListModel;
import javax.swing.JList;


/**
 * Create a JList that shows the contents of a log.
 * By default, only records with level {@link Level#INFO} or higher.
 * By default it only shows 3 rows (which becomes two if placed
 * in a scroll pane).
 */
public class JLoggerList extends JList {
	/**
	 * Keep Eclipse happy
	 */
	private static final long serialVersionUID = 1L;
	private final MyHandler handler;
	
	/**
	 * Create a Swing list viewing the given logger.
	 * @param l logger to view, must not be null.
	 */
	public JLoggerList(Logger l) {
		super(new MyModel());
		handler = new MyHandler((MyModel)this.getModel());
		l.addHandler(handler);
		this.setVisibleRowCount(3); // hard coded
	}
	
	/**
	 * Clear the list; discard all log entries.
	 */
	public void clear() {
		handler.clear();
	}
	
	private class MyHandler extends Handler {

		private final MyModel model;
		
		public MyHandler(MyModel m) {
			model = m;
		}
		
		@Override
		public void close() throws SecurityException {
			// do nothing
		}

		@Override
		public void flush() {
			// do nothing
		}

		@Override
		public void publish(LogRecord record) {
			model.add(record);
		}
		
		public void clear() {
			model.clear();
		}
	}
	
	private static class MyModel extends AbstractListModel {
		/**
		 * Keep Eclipse happy
		 */
		private static final long serialVersionUID = 1L;
		private List<String> buffer = new ArrayList<String>();
		private Level level = Level.INFO; // hard coded for now
		private Formatter formatter = new SimpleFormatter();
		
		public void add(LogRecord r) {
			if (r.getLevel().intValue() >= level.intValue()) {
				buffer.add(formatter.format(r));
				this.fireIntervalAdded(this, buffer.size()-1, buffer.size()-1);
			}
		}
		
		public Object getElementAt(int arg0) {
			return buffer.get(arg0);
		}

		public int getSize() {
			return buffer.size();
		}
		
		public void clear() {
			int n = buffer.size();
			if (n > 0) {
				buffer.clear();
				this.fireIntervalRemoved(this, 0, n-1);
			}
		}
	}
}
